/*
 * ConfigParser.cpp
 *
 *  Created on: 17.05.2011
 *      Author: mifodix
 */

#include "ConfigParser.hpp"

ConfigParser::ConfigParser()
{
}

Settings *ConfigParser::parse(const char *filename)
{
	std::ifstream file(filename);
	if (!file.is_open())
	{
		Logger::Log("ConfigParser", STATE_ERROR, "Can't open configuration file!");
		return NULL;
	}
	Settings *setts=new Settings;
	char *line=new char[64];
	char *token;
	bool isFailed=false;
	while (!file.eof() && !isFailed)
	{
		file.getline(line, 64);
		token=strtok(line, " ;");
		if (!token) break;//защита от пустой строки
		if (!strcmp(token, "subnet"))
		{
			token=strtok(NULL, " ;");
			if (!setts->SetSubnet(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid subnet IP-address!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "netmask"))
		{
			token=strtok(NULL, " ;");
			if (!setts->SetNetmask(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid netmask!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "server"))
		{
			token=strtok(NULL, " ;");
			if (!setts->SetServer(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid server IP-address!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "hwadd"))
		{
			token=strtok(NULL, " ;");
			char mac[6];
			char *tempByte=new char[3];
			tempByte[2]='\0';
			for (int i=0, j=0; i<strlen(token)+1; i+=2, j++)//вырезаем ":"
			{
				tempByte[0]=token[i++];
				tempByte[1]=token[i];
				sscanf(tempByte, "%x", &mac[j]);
			}
			delete[] tempByte;
			token=strtok(NULL, " ;");
			if (!setts->AddReservedIP(mac, 6, token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Already used or invalid record!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "default-lease-time"))
		{
			token=strtok(NULL, " ;");
			uint32_t time=atoi(token);
			if (time>0)//если преобразование в число удалось
			{
				setts->SetDefaultLeaseTime(time);
			}
			else
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid default lease time!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "max-lease-time"))
		{
			token=strtok(NULL, " ;");
			uint32_t time=atoi(token);
			if (time>0)//если преобразование в число удалось
			{
				setts->SetMaxLeaseTime(time);
			}
			else
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid max lease time!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "router"))
		{
			token=strtok(NULL, " ;");
			if (!setts->AddRouter(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Already used or invalid router IP-address!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "domain-name-server"))
		{
			token=strtok(NULL, " ;");
			if (!setts->AddDomainNameServer(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Already used or invalid domain name server IP-address!");
				isFailed=true;
			}
		}
		else if (!strcmp(token, "range"))
		{
			token=strtok(NULL, " ;");
			if (!setts->SetRangeBegin(token))
			{
				Logger::Log("ConfigParser", STATE_ERROR, "Invalid range begin IP-address!");
				isFailed=true;
			}
			else
			{
				token=strtok(NULL, " ;");
				if (!setts->SetRangeEnd(token))
				{
					Logger::Log("ConfigParser", STATE_ERROR, "Invalid range end IP-address!");
					isFailed=true;
				}
				if ((int32_t)(setts->GetRangeEnd()-setts->GetRangeBegin())<=0)
				{
					Logger::Log("ConfigParser", STATE_ERROR, "Invalid range!");
					isFailed=true;
				}
			}
		}
		else
		{
			Logger::Log("ConfigParser", STATE_ERROR, "Wrong config file!");
			isFailed=true;
		}
	}
	file.close();
	delete[] line;
	if (isFailed)
	{
		delete setts;
		return NULL;
	}
	else
	{
		Logger::Log("ConfigParser", STATE_INFO, "Configuration file succesfully readed.");
		return setts;
	}
}

ConfigParser::~ConfigParser()
{
}
